package kengxxiao.tabiconhack.coremod;

import java.util.ListIterator;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;

import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;

public class TabIconHackForgeClassTransformer implements IClassTransformer{

	private FMLDeobfuscatingRemapper deobf = FMLDeobfuscatingRemapper.INSTANCE;
	
	@Override
	public byte[] transform(String name, String transformedName, byte[] basicClass) {
		if (transformedName.equals("net.minecraft.client.gui.GuiPlayerTabOverlay"))
		{
			ClassNode classNode = new ClassNode();
            ClassReader classReader = new ClassReader(basicClass);
            classReader.accept(classNode, 0);
            
            MethodNode m = findMethod(classNode, name, "(ILnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/ScoreObjective;)V", "func_175249_a");
            ListIterator<AbstractInsnNode> iterator = m.instructions.iterator();
            while (iterator.hasNext())
            {
            	 AbstractInsnNode node = iterator.next();
            	 if (node instanceof VarInsnNode)
            	 {
            		 VarInsnNode varNode = (VarInsnNode) node;
            		 if (varNode.getOpcode() == Opcodes.ISTORE && varNode.var == 11)
            		 {
            			 m.instructions.set(varNode.getPrevious(), new InsnNode(Opcodes.ICONST_1));
            		 }
            	 }
            }
            
            ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
            classNode.accept(classWriter);
            return classWriter.toByteArray();
		}
		return basicClass;
	}

	private MethodNode findMethod(ClassNode classNode,String obfedClassName , String desc, String... names) {
		for (MethodNode method : classNode.methods) {
			if (desc != null && !desc.equals(deobf.mapMethodDesc(method.desc)))
				continue;

			for (String name : names) {
				if (deobf.mapMethodName(obfedClassName, method.name, method.desc).equals(name))
					return method;
			}
		}
		return null;
	}

}
